#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <vector>
#include <string>
#include <cstring>

using namespace std;

#define NUM 3

__thread int g_val = 100;

struct ThreadData
{
    string threadname;
};

inline void InitThreadData(ThreadData* td, int number)
{
    td->threadname = "thread-"+to_string(number);
}

string thHex(pthread_t tid)
{
    char buffer[1024];
    snprintf(buffer,sizeof(buffer),"0x%x", tid);
    return buffer;
}

void* threadRoutine(void* args)
{
    ThreadData* td = static_cast<ThreadData*>(args);
    cout << td->threadname << " is running!" << endl;
    // for(int i = 0; i < 10; ++i)
    // {
    //     g_val++;
    //     cout << "I am a thread, pid: " << getpid() <<
    //     " tid: " << thHex(pthread_self()) <<
    //     " threadname: " << td->threadname <<
    //     " g_val: " << g_val << " &g_val: " << &g_val << endl;
    //     sleep(1);
    // }
    delete td;
    return nullptr;
}

int main()
{
    vector<pthread_t> tids;

    for(int i = 0; i < NUM; ++i)
    {
        pthread_t tid;
        ThreadData* td = new ThreadData;
        InitThreadData(td, i);

        pthread_create(&tid,nullptr, threadRoutine, td);
        tids.push_back(tid);
    }
    sleep(1);
    for(auto x : tids)
    {
        pthread_detach(x);
    }

    for(int i = 0; i < tids.size(); ++i)
    {
        int n = pthread_join(tids[i], nullptr);
        printf("exit code : %d, tid:0x%x ,error string: %s\n", n, tids[i], strerror(n));
    }

    return 0;
}